<template>
  <div class="box" ref="filecont">
    <!-- 标题信息栏 -->
    <div class="title-bar">
      <div class="fileName" v-if="inputVisible">
        <p>{{ textName }}</p>
        <el-icon class="editPen" @click="editFileName()">
          <EditPen/>
        </el-icon>
      </div>

      <div class="fileName" v-else>
        <el-input v-model="textName" id="InputName" style="width: 240px"/>
        <el-icon class="editPen" @click="sureInput()">
          <Check/>
        </el-icon>
      </div>

      <div>
        <el-button type="primary" plain @click="edit()" v-if="!editFlag" :disabled="editable">编辑</el-button>
        <el-button type="primary" plain @click="save()" v-else>保存</el-button>
        <el-button type="primary" plain @click="share()">分享</el-button>
        <el-button type="primary" plain @click="derive()">导出</el-button>
      </div>
    </div>
    <!-- 操作工具栏 -->
    <div class="tool-bar">
      <!-- 插入 -->
      <div class="insert">
        <el-dropdown trigger="click">
        <span class="el-dropdown-link">
          <el-icon class="icon"
          >
          <Plus style="color: #fff; font-size: 10px; font-weight: bold"
          />
        </el-icon>
        </span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item :icon="PictureFilled"
              >
                <el-upload
                    action=""
                    :auto-upload="false"
                    :on-change="handleChange"
                    :show-file-list="false"
                    style="height: 22px;"
                >图片
                </el-upload>
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>

      </div>
      <EditorMenu style="margin-left: 13px" :editor="editor"/>
    </div>
    <!-- 文本编辑区域 -->
    <div class="editor">
      <editor-content :editor="editor" class="content"
                      @mouseup="selecttext($event)"/>
      <Outline class="view" v-if="outlineVisible" @hideText="hideRight()"></Outline>
    </div>
    <!--    底部数字统计区域-->
    <div class="bottomcount"> 字数统计:
      {{ editor?.storage.characterCount.characters() }}
      <el-button type="primary" plain @click="polish()" v-loading.fullscreen.lock="fullscreenLoading">润色</el-button>
      <el-button type="primary" plain @click="continuation()">续写</el-button>
      <el-button type="primary" plain @click="summary()">总结</el-button>
      <el-button type="primary" plain @click="translate()">翻译</el-button>
      <el-button type="primary" plain @click="compose()">智能排版</el-button>
      <el-button type="primary" plain
                 @click="getPic()">
        图片识别
      </el-button>
    </div>

    <!--    分享弹窗-->
    <el-dialog v-model="shareVisible" title="分享" width="500">
      <el-form>
        <el-form-item label="设置有效期：">
          <el-radio-group v-model="settingType">
            <el-radio :value="7">7天有效</el-radio>
            <el-radio :value="30">30天有效</el-radio>
            <el-radio :value="100">永久有效</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="链接分享：">
          <el-input v-model="linkName" autocomplete="off"/>
        </el-form-item>
        <el-form-item label="设置编辑：">
          <el-switch v-model="range" :change="editChange"/>
        </el-form-item>
        <el-form-item label="" v-show="range === true">
          <div style="width: 500px;display: flex;justify-content: space-between;align-items: center">
            <el-input v-model="editPassword" autocomplete="off" style="margin-right: 20px"/>
            <el-button type="primary" @click="getCode()">生成编辑码</el-button>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="stopShare()">停止分享</el-button>
        </div>
      </template>
    </el-dialog>

    <!--    生成结果的选项框-->
    <el-drawer
        v-model="resultShow"
        title="AI记录"
    >
      <div class="consequence" v-for="(item,index) in resultList">{{ item.cont }}</div>
    </el-drawer>

  </div>
</template>
<script setup>
import {onMounted, ref,} from 'vue';
import {EditorContent, Editor, useEditor} from '@tiptap/vue-3';
import {storeToRefs} from 'pinia'
import Underline from '@tiptap/extension-underline'
import Api from '@/api/index.ts'
// 列表
import ListItem from '@tiptap/extension-list-item'
import OrderedList from '@tiptap/extension-ordered-list'
import BulletList from '@tiptap/extension-bullet-list'
// 代码
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
import css from 'highlight.js/lib/languages/css'
import js from 'highlight.js/lib/languages/javascript'
import ts from 'highlight.js/lib/languages/typescript'
import html from 'highlight.js/lib/languages/xml'
import {common, createLowlight} from 'lowlight'
// 字数统计
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'

import CharacterCount from '@tiptap/extension-character-count'
import Italic from '@tiptap/extension-italic'
import TextAlign from '@tiptap/extension-text-align'
import heading from '@tiptap/extension-heading'
import StarterKit from '@tiptap/starter-kit'
import Placeholder from '@tiptap/extension-placeholder'
import TaskItem from '@tiptap/extension-task-item'
import TaskList from '@tiptap/extension-task-list'
import Image from '@tiptap/extension-image'
import {Color} from '@tiptap/extension-color'
import TextStyle from '@tiptap/extension-text-style'
import Outline from '@/components/Outline/index.vue'
// 使用Pinia
import {useEditorStore} from '@/store/index.js'
import EditorMenu from '@/components/EditMenu/index.vue'
import {defineStore} from 'pinia'
import {ElMessage} from 'element-plus';
import {PictureFilled} from "@element-plus/icons-vue";
import router from "@/router/index.js";
import {useRoute} from "vue-router";
import axios from "axios";
// 加载
import {ElLoading} from 'element-plus'

const lowlight = createLowlight()
lowlight.register({html, ts, css, js})
const editorStore = useEditorStore()
// 加载headings
const loadHeadings = () => {
  const headings = []
  if (!editor.value) return
  const transaction = editor.value.state.tr
  if (!transaction) return

  editor.value?.state.doc.descendants((node, pos) => {
    if (node.type.name === 'heading') {
      console.log(pos, node)
      const start = pos
      const end = pos + node.content.size
      // const end = pos + node
      const id = `heading-${headings.length + 1}`
      if (node.attrs.id !== id) {
        transaction?.setNodeMarkup(pos, undefined, {
          ...node.attrs,
          id
        })
      }

      headings.push({
        level: node.attrs.level,
        text: node.textContent,
        start,
        end,
        id
      })
    }
  })

  transaction?.setMeta('addToHistory', false)
  transaction?.setMeta('preventUpdate', true)

  editor.value?.view.dispatch(transaction)
  editorStore.setHeadings(headings)
}


// 新建文档
const route = useRoute()
const textName = ref('未命名文档')
const textId = ref()

const editFlag = ref(false)
const editable = ref(false)

onMounted(() => {
  console.log(route.query)
  if (route.query.source === 'detail') {
    textId.value = route.query.id;
    Api.lookDocu(textId.value).then((res) => {
      if (res.code === 1) {
        ElMessage.success('获取内容成功');
        if (editor) {
          // 设置编辑器只读
          editor.setEditable(false)
          // 内容赋值
          editor.commands.setContent(res.data.content);
        }
      }
    })
  } else if (route.query.source === 'home') {
    // 设置可编辑，显示保存按钮
    editFlag.value = true
    Api.addText(textName.value, '无', route.query.id, 'document_html').then((res) => {
      if (res.code === 1) {
        ElMessage.success('文本创建成功');
        textName.value = res.data.name;
        textId.value = res.data.id;
      } else {
        ElMessage.error('文本创建失败');
      }
    })
  } else if (route.query.source === 'share') {
    textId.value = route.query.id;
    if (route.query.pwd === 'false') {
      // 预览文档没有编辑权限
      Api.lookDocu(textId.value).then((res) => {
        if (res.code === 1) {
          ElMessage.success('获取内容成功');
          // 不能点击编辑
          editable.value = true;
          console.log(editable.value)
          if (editor) {
            // 设置编辑器只读
            editor.setEditable(false)
            // 内容赋值
            editor.commands.setContent(res.data.content);
          }
        }
      })
    } else if (route.query.pwd === 'true') {
      // 预览文档有编辑权限
      Api.lookDocu(textId.value).then((res) => {
        if (res.code === 1) {
          ElMessage.success('获取内容成功');
          if (editor) {
            // 设置编辑器只读
            editor.setEditable(false)
            // 内容赋值
            editor.commands.setContent(res.data.content);
          }
        }
      })
    } else {
      ElMessage.error("分享有问题")
    }
  } else {
    console.log(other)
  }
})

// 点击编辑设置可编辑
const edit = () => {
  editFlag.value = true
  if (editor) {
    // 设置编辑器可编辑
    editor.setEditable(true)
  }
}

// 使用ref创建可变的响应式引用
// 编辑器初始化
const editor = new Editor({
  content: ``,
  extensions: [
    StarterKit.configure({
      heading: {
        levels: [1, 2, 3, 4],
      },
    }),
    TaskList,
    TaskItem,
    Placeholder.configure({
      placeholder: '开始输入文本 …'
    }),
    OrderedList,
    BulletList,
    ListItem,
    Image,
    Italic,
    TextAlign,
    Color,
    TextStyle,
    CharacterCount.configure({
      limit: 10000
    })
  ],
  onUpdate({edit}) {
    console.log(editor)
    loadHeadings()
    editorStore.setEditorInstance(editor.value)
  },
  onCreate({edit}) {
    loadHeadings()
    editorStore.setEditorInstance(editor.value)
  },
  injectCSS: true,
})


// 上传图片
const imgUrl = ref('')
const handleChange = (file, fileList) => {
// console.log(file, fileList);
  const formData = new FormData();
  formData.append("file", file.raw);
  axios.post('http://1.92.137.88:86/dcLibrary/upload', formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
      'token': localStorage.getItem('token')
    }
  }).then((res) => {
    if (res.data.code === 1) {
      console.log(res)
      if (editor) {
        editor.commands.setImage({src: res.data.data})
        ElMessage({
          message: '图片上传成功',
          type: 'success',
        })
        imgUrl.value = res.data.data;
      }
    }
  })
}

// 获取选中的文字
const filecont = ref(null);
let hisstring = ref('');
var selection;
const selecttext = (e) => {
  selection = window.getSelection();
  if (selection != null && hisstring != selection) {
    let content = selection.toString();
    if (content != "") {
      hisstring.value = content;
      console.log(content)
    }
  } else {
    hisstring.value = ""
  }
}

// 点击产生加载按钮
const fullscreenLoading = ref(false)

//   润色续写
const result = ref('')
// 右侧弹窗
const resultShow = ref(false)
// 存放结果的列表
const resultList = ref([{cont: "我有一个苹果"}, {cont: "我有一个苹果"}, {cont: "我有一个苹果"},])
//进行润色的函数
const polish = () => {
  // 先push列表
  resultList.value.push({cont: hisstring.value})
  // 显示加载
  fullscreenLoading.value = true;
  let url = 'http://1.92.137.88:86/ai/polish' //访问后端接口的url
  let method = 'post'
  axios({
    method,
    url,
    data: {"cont": hisstring.value},
  }).then(res => {
    if (res.data.code === 1) {
      ElMessage.success("成功")
      fullscreenLoading.value = false;
      resultShow.value = true;
      result.value = JSON.parse(res.data.data).answer;
      resultList.value.push({cont: result.value})
      hisstring.value = ""
    } else {
      ElMessage.error("失败")
    }
  });
}

//进行续写
const continuation = () => {
  // 先push列表
  resultList.value.push({cont: hisstring.value})
  // 显示加载
  fullscreenLoading.value = true;
  let url = 'http://1.92.137.88:86/ai/continuation' //访问后端接口的url
  let method = 'post'
  axios({
    method,
    url,
    data: {"cont": hisstring.value},
  }).then(res => {
    if (res.data.code === 1) {
      ElMessage.success("成功")
      fullscreenLoading.value = false;
      resultShow.value = true;
      result.value = JSON.parse(res.data.data).answer;
      resultList.value.push({cont: result.value})
      hisstring.value = ""
    } else {
      ElMessage.error("失败")
    }
  });
}


// 总结
const summary = () => {
  // 先push列表
  resultList.value.push({cont: hisstring.value})
  // 显示加载
  fullscreenLoading.value = true;
  let url = 'http://1.92.137.88:86/ai/getabstract' //访问后端接口的url
  let method = 'post'
  axios({
    method,
    url,
    data: {"cont": hisstring.value},
  }).then(res => {
    if (res.data.code === 1) {
      ElMessage.success("成功")
      fullscreenLoading.value = false;
      resultShow.value = true;
      result.value = JSON.parse(res.data.data).answer;
      resultList.value.push({cont: result.value})
      hisstring.value = ""
    } else {
      ElMessage.error("失败")
    }
  });
}

// 翻译
const translate = () => {
  // 先push列表
  resultList.value.push({cont: hisstring.value})
  // 显示加载
  fullscreenLoading.value = true;
  let url = 'http://1.92.137.88:86/ai/translates' //访问后端接口的url
  let method = 'post'
  axios({
    method,
    url,
    data: {"cont": hisstring.value},
  }).then(res => {
    if (res.data.code === 1) {
      ElMessage.success("成功")
      fullscreenLoading.value = false;
      resultShow.value = true;
      result.value = JSON.parse(res.data.data).answer;
      resultList.value.push({cont: result.value})
      hisstring.value = ""
    } else {
      ElMessage.error("失败")
    }
  });
}
// 获取图片内容
const getPic = () => {
  // 显示加载
  fullscreenLoading.value = true;
  let url = 'http://1.92.137.88:86/ai/imgocr?userId=1&imgUrl=' + imgUrl.value //访问后端接口的url
  let method = 'post'
  axios({
    method,
    url,
  }).then(res => {
    if (res.data.code === 1) {
      fullscreenLoading.value = false;
      ElMessage({
        message: '图片识别成功',
        type: 'success',
      })
      let data = JSON.parse(res.data.data);
      let distinguish = '';
      for (let i = 0; i < data.content.length; i++) {
        distinguish += data.content[i] + ''
      }
      //   插入内容
      if (editor) {
        editor.commands.insertContent(distinguish)
      }
    } else {
      ElMessage.error("失败")
    }
  });
}

//智能排版
const compose = () => {
  if (editor) {
    editor.commands.insertContent('<h1>This is a 1st level heading</h1>\n' +
        '        <h2>This is a 2nd level heading</h2>\n' +
        '        <h3>This is a 3rd level heading</h3>\n' +
        '        <h4>This 4th level heading will be converted to a paragraph, because levels are configured to be only 1, 2 or 3.</h4>')
  }
  // // 显示加载
  // fullscreenLoading.value = true;
  // let url = 'http://1.92.137.88:86/ai/getTypesetting' //访问后端接口的url
  // let method = 'post'
  // axios({
  //   method,
  //   url,
  //   data: {"cont": hisstring.value},
  // }).then(res => {
  //   console.log(res.data.data)
  //   if (res.data.code === 1) {
  //     ElMessage.success("成功")
  //     fullscreenLoading.value = false;
  //     // resultShow.value = true;
  //     // result.value = JSON.parse(res.data.data).answer;
  //     // resultList.value.push({cont: result.value})
  //     // hisstring.value = ""
  //   } else {
  //     ElMessage.error("失败")
  //   }
  // });
}


// 隐藏大纲
const outlineVisible = ref(true)
const hideRight = () => {
  outlineVisible.value = !outlineVisible.value
}

// 修改文件名
const inputVisible = ref(true)
const editFileName = () => {
  inputVisible.value = false
}

const sureInput = () => {
  inputVisible.value = true;
  Api.setInfo({id: textId.value, name: textName.value}).then((res) => {
    if (res.code === 1) {
      ElMessage({
        message: '修改成功',
        type: 'success',
      })
    } else {
      ElMessage.error('修改失败')
    }
  })
}

// 保存
const save = () => {
  if (editor) {
    const content = editor.getHTML()
    Api.saveText(textId.value, content).then((res) => {
      if (res.code === 1) {
        ElMessage({
          message: '保存成功',
          type: 'success',
        })
        if (editor) {
          // 设置编辑器可编辑
          editor.setEditable(false)
        }
        editFlag.value = false
      } else {
        ElMessage.error('保存失败')
      }
    })
  }
}

// 分享
const shareVisible = ref(false)

const settingType = ref(100)

const linkName = ref('')

const range = ref(false)

const type = ref('CREATE_URL')

const editPassword = ref('')

const editChange = () => {
  range.value = !range.value
  const data = {id: textId.value, settingType: type.value, share: true, validityType: 'SEVEN_DAY'}
  if (type.value === 'PWD') {
    data.pwd = editPassword.value;
    Api.setShare(data).then(res => {
      console.log(res)
      shareFlag.value = false
    })
  } else {
    Api.setShare(data).then(res => {
      console.log(res)
      shareFlag.value = false
    })
  }
}

const shareFlag = ref(true)
const share = () => {
  shareVisible.value = true
  const data = {id: textId.value, settingType: type.value, share: true, validityType: 'SEVEN_DAY'}
  if (type.value === 'PWD') {
    data.pwd = editPassword.value;
    Api.setShare(data).then(res => {
      if (res.code === 1) {
        linkName.value = res.data.shareKey
      }
      shareFlag.value = false
    })
  } else {
    Api.setShare(data).then(res => {
      if (res.code === 1) {
        linkName.value = res.data.shareKey
      }
      shareFlag.value = false
    })
  }
}

// 生成密码后重新发起请求
const getCode = () => {
  const data = {id: textId.value, settingType: type.value, share: true, validityType: 'SEVEN_DAY'}
  if (type.value === 'PWD') {
    data.pwd = editPassword.value;
    Api.setShare(data).then(res => {
      if (res.code === 1) {
        linkName.value = res.data.shareKey
      }
      shareFlag.value = false
    })
  } else {
    Api.setShare(data).then(res => {
      if (res.code === 1) {
        linkName.value = res.data.shareKey
      }
      shareFlag.value = false
    })
  }
}

// 停止分享
const stopShare = () => {
  const data = {id: textId.value, settingType: type.value, share: false, validityType: 'SEVEN_DAY'}
  if (type.value === 'PWD') {
    data.pwd = editPassword.value;
    Api.setShare(data).then(res => {
      if (res.code === 1) {
        ElMessage({
          message: '停止分享成功',
          type: 'success',
        })
      }
      shareFlag.value = false
    })
  } else {
    Api.setShare(data).then(res => {
      if (res.code === 1) {
        ElMessage({
          message: '停止分享成功',
          type: 'success',
        })
      }
      shareFlag.value = false
    })
  }
}


// 导出
const derive = () => {

}

</script>
<style scoped lang="less">
.box {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  font-size: 15px;

  .title-bar {
    width: 96%;
    height: 55px;
    border-bottom: 1px solid #ddd;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 20px;

    .fileName {
      display: flex;
      justify-content: space-evenly;
      align-items: center;

      .editPen {
        margin-left: 10px;
        font-size: 18px;
      }
    }
  }

  .tool-bar {
    width: 96%;
    height: 40px;
    background-color: #fff;
    border-bottom: 1px solid #ddd;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    padding: 0 20px;

    .insert {
      padding-right: 18px;
      cursor: pointer;
      border-right: 1px solid #ccc;

      .icon {
        background-color: #409eff;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 19px;
        height: 19px;
        border-radius: 50%;
      }
    }

    .size {
      padding-left: 25px;
      cursor: pointer;
    }
  }

  .editor {
    box-sizing: border-box;
    position: relative;
    width: 96%;
    height: 80%;
    margin: 10px 0;
    padding: 10px;
    overflow: hidden;

    .content {
      box-sizing: border-box;
      width: 78%;
      height: 74vh;
      overflow-y: auto;
    }

    .view {
      box-sizing: border-box;
      position: absolute;
      top: 10px;
      right: 10px;
      padding-left: 20px;
      height: 74vh;
      width: 20%;
      border-left: 1px solid #ccc;
    }
  }

  //润色续写
  .contextmenu {
    width: 180px;
    margin: 0;
    background: #fff;
    z-index: 3000;
    position: absolute;
    list-style-type: none;
    padding: 5px;
    padding-left: 15px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 400;
    color: #333;
    box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
    display: grid;
    grid-template-columns:50% 50%;

    .item {
      height: 35px;
      width: 100%;
      line-height: 35px;
      color: rgb(29, 33, 41);
      cursor: pointer;
    }

    .item:hover {
      background: rgb(229, 230, 235);
    }
  }
}


b {
  font-weight: bold;
}

.ProseMirror {
  overflow-y: scroll;
}

.ProseMirror p {
  margin: 0;
}

.ProseMirror:focus {
  outline: none;
}

.tiptap p.is-editor-empty:first-child::before {
  color: #adb5bd;
  content: attr(data-placeholder);
  float: left;
  height: 0;
  pointer-events: none;
}

.tiptap {
  > * + * {
    margin-top: 0.75em;
  }

  ul {
    padding: 0 2rem;
    list-style: square;
  }

  ol {
    padding: 0 2rem;
    list-style: decimal;
  }

  table {
    border-collapse: collapse;
    table-layout: fixed;
    width: 100%;
    margin: 0;
    overflow: hidden;

    td,
    th {
      min-width: 1em;
      border: 2px solid #ced4da;
      padding: 3px 5px;
      vertical-align: top;
      box-sizing: border-box;
      position: relative;

      > * {
        margin-bottom: 0;
      }
    }

    th {
      font-weight: bold;
      text-align: left;
      background-color: #f1f3f5;
    }

    .selectedCell:after {
      z-index: 2;
      position: absolute;
      content: '';
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      background: rgba(200, 200, 255, 0.4);
      pointer-events: none;
    }

    .column-resize-handle {
      position: absolute;
      right: -2px;
      top: 0;
      bottom: -2px;
      width: 4px;
      background-color: #adf;
      pointer-events: none;
    }

    p {
      margin: 0;
    }
  }

  pre {
    background: #0d0d0d;
    color: #fff;
    font-family: 'JetBrainsMono', monospace;
    padding: 0.75rem 1rem;
    border-radius: 0.5rem;

    code {
      color: inherit;
      padding: 0;
      background: none;
      font-size: 0.8rem;
    }

    .hljs-comment,
    .hljs-quote {
      color: #616161;
    }

    .hljs-variable,
    .hljs-template-variable,
    .hljs-attribute,
    .hljs-tag,
    .hljs-name,
    .hljs-regexp,
    .hljs-link,
    .hljs-name,
    .hljs-selector-id,
    .hljs-selector-class {
      color: #f98181;
    }

    .hljs-number,
    .hljs-meta,
    .hljs-built_in,
    .hljs-builtin-name,
    .hljs-literal,
    .hljs-type,
    .hljs-params {
      color: #fbbc88;
    }

    .hljs-string,
    .hljs-symbol,
    .hljs-bullet {
      color: #b9f18d;
    }

    .hljs-title,
    .hljs-section {
      color: #faf594;
    }

    .hljs-keyword,
    .hljs-selector-tag {
      color: #70cff8;
    }

    .hljs-emphasis {
      font-style: italic;
    }

    .hljs-strong {
      font-weight: 700;
    }
  }

  img {
    width: 200px;
    height: 150px;
  }
}

.tableWrapper {
  overflow-x: auto;
}

.custom-class {
  width: 200px;
}

//结果展示
.consequence {
  display: flex;
  align-items: center;
  font-size: 16px;
  margin: 8px 0;
  border: 1px solid #ccc;
  padding: 6px 0;
}

</style>
